/*******************************************************************************
 * 程序功能：
 * 平安力合采购的12232屏幕的试验
 * 
 ******************************************************************************/
#include "../lib/inc/stm8s.h"
#include "../lib/inc/stm8s_clk.h"
#include "../lib/inc/stm8s_gpio.h"
#include "string.h"

/*******************************************************
 * 延迟1ms
 *******************************************************/
void DelayMS(u16 count)
{
	int j;
	while (count--)
	{
		j = 150;
		while (j--);
	}
}

/*******************************************************
 * 延迟1次,约20um;当计数10时,约48um;当计数100时,约315um
 *******************************************************/
void DelayUS(u8 count)
{
	while (count--);
}

/*******************************************************
 * 时钟初始化
 *******************************************************/
void CLK_Initialize()
{
	CLK_HSICmd(ENABLE);
	CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
}

/*******************************************************
 * GPIO引脚初始化
 *******************************************************/
void GPIO_Initialize()
{
	GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_SLOW);
}

#define LCD_RS		GPIO_PIN_6 
#define LCD_RW		GPIO_PIN_4
#define LCD_CLK		GPIO_PIN_2

#define LCD_BUSY_BIT 7

// LCD引脚定义
#define CLK0()	GPIO_WriteLow(GPIOD,LCD_CLK)
#define CLK1()	GPIO_WriteHigh(GPIOD,LCD_CLK)
#define RW0()	GPIO_WriteLow(GPIOD,LCD_RW)
#define RW1()	GPIO_WriteHigh(GPIOD,LCD_RW)
#define CS0()	GPIO_WriteLow(GPIOD,LCD_RS)
#define CS1()	GPIO_WriteHigh(GPIOD,LCD_RS)

u8 lcd_read_byte()
{
	u8 i, temp1, temp2;
	temp1 = temp2 = 0;
	for (i = 0; i < 8; i++)
	{
		temp1 = temp1 << 1;
		CLK1();
		if (GPIO_ReadInputPin(GPIOD, LCD_RW))
			temp1++;
		CLK0();
	}
	for (i = 0; i < 8; i++)
	{
		temp2 = temp2 << 1;
		CLK1();
		if (GPIO_ReadInputPin(GPIOD, LCD_RW))
			temp2++;
		CLK0();
	}
	return ((0xF0 & temp1) + (0x0F & temp2));
}

void lcd_write_byte(u8 data)
{
	u8 i;
	for (i = 0; i < 8; i++)
	{
		CLK1();
		if (data & 0x80)
		{
			RW1();
		}
		else
		{
			RW0();
		}
		CLK0();
		data = data << 1;
	}
}

void lcd_check_busy()
{
	do
	{
		lcd_write_byte(0xFC); //11111,RW(1),RS(0),0
	}
	while (0x80 & lcd_read_byte()); //BF(.7)=1 Busy
}

void lcd_write_data(u8 data)
{
	CS1();
	lcd_check_busy();
	lcd_write_byte(0xFA); //11111-RW(0)-RS(1)-0
	lcd_write_byte(0xF0 & data); //高4位
	lcd_write_byte(0xF0 & data << 4); //低4位
	CS0();
}

void lcd_write_command(u8 command)
{
	CS1();
	lcd_check_busy();
	lcd_write_byte(0xF8); //11111-RW(0)-RS(0)-0
	lcd_write_byte(0xF0 & command); //高4位
	lcd_write_byte(0xF0 & command << 4); //低4位
	CS0();
}

void lcd_clear()
{
	lcd_write_command(0x01);
	DelayUS(10);
}

void lcd_initialize()
{
	GPIO_Init(GPIOD, LCD_CLK, GPIO_MODE_OUT_PP_HIGH_SLOW);
	GPIO_Init(GPIOD, LCD_RS, GPIO_MODE_OUT_PP_HIGH_SLOW);
	GPIO_Init(GPIOD, LCD_RW, GPIO_MODE_OUT_PP_HIGH_SLOW);

	DelayMS(50);

	CS1();
	lcd_write_byte(0x30);
	CS0();
	DelayUS(150);
	CS1();
	lcd_write_byte(0x30);
	CS0();
	DelayUS(150);
	CS1();
	lcd_write_byte(0x30);
	CS0();
	DelayUS(150);
	CS1();
	lcd_write_byte(0x0F);
	CS0();
	DelayUS(150);
	CS1();
	lcd_write_byte(0x3C);
	CS0();
	DelayUS(150);

	lcd_write_command(0x38);
	DelayUS(5);
	lcd_write_command(0x02);//清DDRAM
	DelayUS(5);
	lcd_write_command(0x0C);//整体显示开，游标关，反白关	
	DelayUS(5);
	lcd_write_command(0x01);//设定DDRAM的地址计数器(AC)到"00H",并且将游标移到开头原点位置; 
	DelayUS(5);
	lcd_write_command(0x80);//设定首次显示位置	
	DelayMS(1);
}

void lcd_display_chars(u8 row, u8 col, u8* puts)
{
	lcd_write_command((0x80 + 16 * row) | col);
	while (*puts != '\0')
	{
		lcd_write_data(*puts);
		puts++;
	}
	lcd_write_command(0x30);
}

void lcd_display_cn_chars(uint8_t row, uint8_t col, const uint8_t* puts)
{
	lcd_write_command((0x80 + 16 * row) | col);
	while (*puts != '\0')
	{
		lcd_write_data(*puts); //1个汉字写两字节
		puts++;
		lcd_write_data(*puts);
		puts++;
	}
	lcd_write_command(0x30);
}

//测试函数，测试绘图
void lcd_display_dotbytes(unsigned char dotbyte, u8 isV)
{
	unsigned char i, j;
	lcd_write_command(0x36); //8位，扩充指令开，绘图开
	for (i = 0; i < 32; i++)
	{
		lcd_write_command(0x80 | i);// 行位置
		lcd_write_command(0x80);// 列位置
		for (j = 0; j < 16; j++) //15列
		{
			lcd_write_data(dotbyte);
		}
		if (isV)
			dotbyte = ~dotbyte;
	}
	lcd_write_command(0x30);//8位，扩充指令关，绘图关
}

void lcd_drawfull()
{
	unsigned char i, j;
	lcd_write_command(0x36); //8位，扩充指令开，绘图开
	for (i = 0; i < 32; i++)
	{
		lcd_write_command(0x80 | i);// 行位置
		lcd_write_command(0x80);// 列位置
		for (j = 0; j < 16; j++) //15列
		{
			lcd_write_data(0xFF);
		}
	}
	for (i = 0; i < 32; i++)
	{
		lcd_write_command(0x80 | i);// 行位置
		lcd_write_command(0x80);// 列位置
		for (j = 0; j < 16; j++) //15列
		{
			lcd_write_data(0x00);
		}
	}
	lcd_write_command(0x30);//8位，扩充指令关，绘图关
}


// 函数名：unsigned charFloat2Char(float Value,char *array)
// 描 述：将浮点数的各个位的数值转换成字符串，通过串口发送至上位机显示
// 参 数：float Value为欲转换的正数浮点数值，转换结果保存在字符数组*array里
unsigned char Float2Char(float value, unsigned char* array)
{
	u8 IntegerPart;
	float DecimalPart;
	u8 i = 0;
	u8 j = 0;
	char temp;

	//分离整数和小数
	if (value >= 1)
	{
		IntegerPart = (u8)value;
		DecimalPart = value - IntegerPart;
	}
	else
	{
		IntegerPart = 0;
		DecimalPart = value - IntegerPart;
	}

	//处理整数部分
	if (IntegerPart == 0)
	{
		array[0] = '0';
		array[1] = '.';
		i = 1;
	}
	else
	{
		while (IntegerPart > 0)
		{
			array[i] = IntegerPart % 10 + '0';
			IntegerPart /= 10;
			i++;
		}
		i--;

		//fix the result
		for (j = 0; j < i; j++)
		{
			temp = array[j];
			array[j] = array[i - j];
			array[i - j] = temp;
		}
		i++;
		array[i] = '.';
	}

	//convert the Decimalpart
	i++;
	array[i++] = (u32)(DecimalPart * 10) % 10 + '0';
	array[i++] = (u32)(DecimalPart * 100) % 10 + '0';
	array[i++] = (u32)(DecimalPart * 1000) % 10 + '0';
	array[i++] = (u32)(DecimalPart * 10000) % 10 + '0';
	array[i++] = (u32)(DecimalPart * 100000) % 10 + '0';
	array[i] = '\0';

	return i;
}

void main(void)
{
	CLK_Initialize();
	GPIO_Initialize();

	GPIO_Init(GPIOD, LCD_RS, GPIO_MODE_OUT_PP_LOW_SLOW);
	GPIO_Init(GPIOD, LCD_CLK, GPIO_MODE_OUT_PP_LOW_SLOW);
	GPIO_Init(GPIOD, LCD_RW, GPIO_MODE_OUT_PP_LOW_SLOW);

	for (int i = 0; i < 12; i++)
	{
		GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
		DelayMS(80);
	}

	lcd_initialize();
	lcd_clear();

	DelayMS(5);
	lcd_drawfull();
	DelayMS(200);

	while (1)
	{
		lcd_clear();

		lcd_display_cn_chars(0, 0, text1);
		lcd_display_cn_chars(1, 0, text2);
		DelayMS(5000);

		lcd_clear();
		lcd_display_chars(0, 0, "ABCDEFGHYXKLMNQ");
		lcd_display_chars(1, 0, "123456789012345");
		DelayMS(2000);

		lcd_clear();

		lcd_display_dotbytes(0x55, 1);
		DelayMS(800);

		lcd_clear();
		lcd_display_chars(0, 0, "VOLT:        v");
		lcd_display_chars(1, 0, "CURR:        mA");
		DelayMS(1000);

		u8 view[20];
		for (int i = 0; i < 90000; i += 923)
		{
			float j = i * 0.00001;
			Float2Char(j, view);
			lcd_display_chars(0, 3, view);
			lcd_display_chars(1, 3, view);
			DelayMS(30);
		}
		DelayMS(1000);
	}
}

#ifdef USE_FULL_ASSERT

void assert_failed(u8* file, u32 line)
{
	while (1)
	{
	}
}

#endif


/************************ (C) COPYRIGHT xknife.net *************END OF FILE****/

